package gamagora.game.map
{
	import flash.events.Event;
	
	import gamagora.game.OSPlayState;
	import gamagora.game.OSPlayer;
	import gamagora.game.map.backgrounds.OSBackground1;
	import gamagora.game.map.backgrounds.OSBackground2;
	import gamagora.game.map.backgrounds.OSBackground3;
	import gamagora.game.map.backgrounds.OSBackground4;
	import gamagora.game.map.backgrounds.OSBackground5;
	import gamagora.game.map.parts.OSDemoMap1;
	import gamagora.game.map.parts.OSDemoMap2;
	import gamagora.game.map.parts.OSDemoMap3;
	import gamagora.game.map.parts.OSDemoMap4;
	import gamagora.game.map.parts.OSDemoMap5;
	import gamagora.game.map.parts.OSMap1;
	import gamagora.game.map.parts.OSMap2;
	import gamagora.game.map.parts.OSMap3;
	import gamagora.game.map.parts.OSMap4;
	import gamagora.game.map.parts.OSMap5;
	import gamagora.game.map.parts.OSMap6;
	import gamagora.game.map.parts.OSMap7;
	import gamagora.game.utils.OSImages;
	
	import org.flixel.FlxCamera;
	import org.flixel.FlxG;
	import org.flixel.FlxGroup;
	import org.flixel.FlxSprite;

	public class OSWorldMap extends FlxGroup
	{
		public static const _BACKGROUND1_SPEED:Number = 0.05;
		public static const _BACKGROUND2_SPEED:Number = 0.075;
		public static const _BACKGROUND3_SPEED:Number = 0.1;
		
		private static const PLAYER_START_X:uint = 400; // 6000
		private static const PLAYER_START_Y:uint = 50; // 0
		private static const MID_SCREEN_WIDTH:uint = FlxG.width / 2;
		
		private static var _player:OSPlayer;
		private static var _scrollLeftBound:Number;
		private static var _scrollRightBound:Number;
		
		//Scrolling layers
		private static var _background1:OSLayer;
		private static var _background2:OSLayer;
		private static var _background3:OSLayer;
		
		private var _nbSprites:uint;
		private var _maps:Vector.<OSMap>;
		private var _currentMap:uint;
		private var _nextMap:Boolean;
		private var _previousMap:Boolean;
		private var _visibleNext:Boolean;
		private var _visiblePrevious:Boolean;
		private var _sunBackground:FlxSprite;
		
		public function OSWorldMap()
		{
			_nbSprites = 0;
			_currentMap = 0;
			
			_background1 = new OSLayer(_BACKGROUND1_SPEED);
			_background2 = new OSLayer(_BACKGROUND2_SPEED);
			_background3 = new OSLayer(_BACKGROUND3_SPEED);
			
			//Maps
			_maps = new Vector.<OSMap>();
/*
			_maps.push(new OSMap1());
			_maps.push(new OSMap2());
			_maps.push(new OSMap3());
			_maps.push(new OSMap4());
			_maps.push(new OSMap5());
			_maps.push(new OSMap6());
			_maps.push(new OSMap7());
*/
			//Maps
			_maps = new Vector.<OSMap>();
			_maps.push(new OSDemoMap1);
			_maps.push(new OSDemoMap2);
			_maps.push(new OSDemoMap3);
			_maps.push(new OSDemoMap4);
			_maps.push(new OSDemoMap5);
			
			/*
			_maps.push(new OSMap1());
			_maps.push(new OSMap2());
			_maps.push(new OSMap3());
			_maps.push(new OSMap4());
			_maps.push(new OSMap5());
			_maps.push(new OSMap6());
			_maps.push(new OSMap7());
			*/			
			//Layers
			
			var v:Vector.<uint> = new Vector.<uint>();
			v.push(3);
			v.push(4);
			
			_background3.addBackground(new OSBackground1());
			_background3.addBackground(new OSBackground2());
			_background3.addBackground(new OSBackground3());
			_background3.addBackground(new OSBackground4());
			_background3.addBackground(new OSBackground5());
			_background3.addSpecials(v, 3);
			_background3.generateRandomSequence(_maps.length * 2);
			
			_background2.addBackground(new OSBackground(OSImages.N1P3));
			_background2.addBackground(new OSBackground(OSImages.N2P2));
			_background2.addBackground(new OSBackground(OSImages.N3P3));
			_background2.addBackground(new OSBackground(OSImages.E1P3));
			_background2.addBackground(new OSBackground(OSImages.E2P3));
			_background2.addSpecials(v, 3);
			_background2.generateRandomSequence(_maps.length * 2);
			
			
			
			_background1.addBackground(new OSBackground(OSImages.N1P4));
			_background1.addBackground(new OSBackground(OSImages.N2P4));
			_background1.addBackground(new OSBackground(OSImages.N3P4));
			_background1.addBackground(new OSBackground(OSImages.E1P4));
			_background1.addBackground(new OSBackground(OSImages.E2P4));
			_background1.addSpecials(v, 3);
			_background1.generateRandomSequence(_maps.length * 2);
			
			_currentMap = 0;
			_nbSprites = 0;
			_nbSprites += _maps[_currentMap].pushObjects(this);
			
			
			_sunBackground = new FlxSprite(0, 0, OSImages.BG);
			_sunBackground.scrollFactor.x = 0;
			_nbSprites++;
			add(_sunBackground);
			
			//Player and camera			
			_player = new OSPlayer(PLAYER_START_X, PLAYER_START_Y);
			_player.create(this);
			_nbSprites++;
			add(_player);
			
			//Scrolls
			_scrollLeftBound = OSMap.WIDTH / 2;
			_scrollRightBound =  _maps.length * OSMap.WIDTH - _scrollLeftBound; 
			
			FlxG.camera.follow(_player, FlxCamera.STYLE_LOCKON);
			FlxG.camera.setBounds(0, 0, OSMap.WIDTH * _maps.length, OSMap.HEIGHT);
		}
		
		public override function update():void
		{
			super.update();
			_nextMap = _currentMap + 1 < _maps.length;
			_previousMap = _currentMap - 1 >= 0;
			_visibleNext = _visiblePrevious = false;
			
			if(_nextMap)
			{
				_visibleNext = _maps[_currentMap + 1].leftClosed(_player.x + _player.halfWidth + MID_SCREEN_WIDTH, 0);
				
				//Chargement des objets de la carte suivante à l'avance
				if(!_maps[_currentMap + 1].inGame)
				{
					if(_maps[_currentMap + 1].leftClosed(_player.x + _player.halfWidth + MID_SCREEN_WIDTH))
					{
						_nbSprites += _maps[_currentMap + 1].pushObjects(this);
						
						//Déchargement des objets de la carte précédente
						if(_previousMap && _maps[_currentMap - 1].inGame)
						{
							_nbSprites -= _maps[_currentMap - 1].removeObjects(this);
						}
					}
				}
			}
			
			if(_previousMap)
			{
				_visiblePrevious = _maps[_currentMap - 1].rightClosed(_player.x + _player.halfWidth - MID_SCREEN_WIDTH, 0);
				
				//Chargement des objets de la carte précédente à l'avance
				if(!_maps[_currentMap - 1].inGame)
				{
					if(_maps[_currentMap - 1].rightClosed(_player.x + _player.halfWidth - MID_SCREEN_WIDTH))
					{
						_nbSprites += _maps[_currentMap - 1].pushObjects(this);
						
						//Déchargement des objets de la carte suivante
						if(_nextMap && _maps[_currentMap + 1].inGame)
						{
							_nbSprites -= _maps[_currentMap + 1].removeObjects(this);
						}
					}
				}
			}
			
		}
		
		public override function draw():void
		{
			//Background
			_sunBackground.draw();
			
			_background1.draw();
			_background2.draw();
			_background3.draw();
			
			if(_visiblePrevious)
			{
				_maps[_currentMap - 1].drawBackgrounds();
			}
			else if(_visibleNext)
			{
				_maps[_currentMap + 1].drawBackgrounds();	
			}
			
			_maps[_currentMap].drawBackgrounds();
			
			//Objects
			if(_visiblePrevious)
			{
				_maps[_currentMap - 1].draw();
			}
			else if(_visibleNext)
			{
				_maps[_currentMap + 1].draw();	
			}
			
			_maps[_currentMap].draw();
			
			//Player
			_player.draw();
			
			//Foregrounds
			if(_visiblePrevious)
			{
				_maps[_currentMap - 1].drawForegrounds();
			}
			else if(_visibleNext)
			{
				_maps[_currentMap + 1].drawForegrounds();	
			}
			
			_maps[_currentMap].drawForegrounds();
					
			//Mise à jour de la carte courante
			if(!_maps[_currentMap].inside(_player.x + _player.halfWidth))
			{ 
				if(_visibleNext)
				{
					_currentMap++;
				}
				else 
				{
					if(_visiblePrevious)
					{
						_currentMap--;	
					}
				}
			}
		}
		
		public override function destroy():void
		{
			super.destroy();
			_background1.destroy();
			_background2.destroy();
			_background3.destroy();
		}
		
		//Getters Setters
		
		public function get nbSprites():uint
		{
			return _nbSprites;
		}

		public static function get player():OSPlayer
		{
			return _player;
		}

		public function get currentMap():uint
		{
			return _currentMap;
		}

		public static function get scrollLeftBound():Number
		{
			return _scrollLeftBound;
		}

		public static function get scrollRightBound():Number
		{
			return _scrollRightBound;
		}

		public static function get background1():OSLayer
		{
			return _background1;
		}
		
		public static function get background2():OSLayer
		{
			return _background2;
		}
		
		public static function get background3():OSLayer
		{
			return _background3;
		}
	}
}
